﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Consul;
using Infrastructure.Centers;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace Infrastructure.Helper
{
    /// <summary>
    /// Cookie 操作工具类：提供HTTP上下文中Cookie和Header的读写管理
    /// （包含异常处理和多级域名适配）
    /// </summary>
    public static class CookieHelper
    {
        /// <summary>
        /// 写入Cookie（自动处理域名作用域）
        /// </summary>
        /// <param name="HttpContext">HTTP上下文</param>
        /// <param name="Key">Cookie键名</param>
        /// <param name="Value">Cookie值</param>
        /// <param name="ExpTimeSec">过期时间（秒，默认1小时）</param>
        /// <remarks>
        /// 域名处理逻辑：
        /// www.example.com → .example.com
        /// app.dev.example.com → .example.com
        /// localhost → localhost
        /// </remarks>
        public static void WriteCookie(this HttpContext HttpContext, string Key, string Value, int ExpTimeSec = 3600)
        {
            // 获取请求的主机名（不带端口）
            string host = HttpContext.Request.Host.Host;
            string domain;

            try
            {
                // 分割域名并判断层级
                var hostParts = host.Split('.');
                domain = (hostParts.Length <= 1)
                    ? host // 单段域名（如localhost）
                    : string.Join('.', hostParts[^2..]); // 取最后两段（支持多级子域）
            }
            catch (Exception)
            {
                // 异常回退（如空值等情况）
                domain = host;
            }

            // 配置Cookie选项
            CookieOptions options = new CookieOptions
            {
                Expires = DateTime.Now.AddSeconds(ExpTimeSec), // 绝对过期时间
                Path = "/",                                   // 全站有效
                Domain = domain,                              // 作用域名
                                                              // 注意：建议添加 SameSite 和 Secure 设置
                                                              // SameSite = SameSiteMode.Lax,
                                                              // Secure = true // 生产环境应启用
            };

            // 写入响应Cookie
            HttpContext.Response.Cookies.Append(Key, Value, options);
        }

        /// <summary>
        /// 读取Cookie值（空值安全）
        /// </summary>
        /// <returns>存在返回实际值，否则返回空字符串</returns>
        public static string ReadCookie(this HttpContext HttpContext, string strName)
        {
            return HttpContext.Request.Cookies.TryGetValue(strName, out var value)
                ? value ?? string.Empty
                : string.Empty;
        }

        /// <summary>
        /// 读取请求头值（空值安全）
        /// </summary>
        /// <returns>存在返回实际值，否则返回空字符串</returns>
        public static string ReadHeader(this HttpContext HttpContext, string strName)
        {
            return HttpContext.Request.Headers.TryGetValue(strName, out var headerValues)
                ? headerValues.ToString() ?? string.Empty
                : string.Empty;
        }

        /// <summary>
        /// 写入请求头（注意：请求头通常在请求开始时设置，此方法可能不生效）
        /// </summary>
        /// <remarks>
        /// 警告：HttpContext.Request.Headers 是只读集合，
        /// 此操作可能在部分框架中引发异常，建议仅在中间件中使用
        /// </remarks>
        public static void WriteHeader(this HttpContext HttpContext, string strName, string Value)
        {
            HttpContext.Request.Headers[strName] = Value;
        }

        /// <summary>
        /// 删除指定Cookie（客户端下次请求将不再携带）
        /// </summary>
        /// <returns>是否成功删除</returns>
        public static bool ClearCookie(this HttpContext HttpContext, string strName)
        {
            try
            {
                // 通过设置空值+过期时间使浏览器删除Cookie
                HttpContext.Response.Cookies.Delete(strName, new CookieOptions
                {
                    Expires = DateTime.Now.AddDays(-1), // 设置为过去时间
                    Domain = HttpContext.Request.Host.Host
                });
                return true;
            }
            catch (Exception ex)
            {
                // 建议记录日志
                return false;
            }
        }
    }
}
